home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 September / PCWorld_2008-09_cd.bin / v cisle / sadanastroju / greasemonkey-0.8.20080609.0-fx.xpi / chrome / greasemonkey.jar / chromeFiles / content / browser.js < prev    next >
Text File  |  2008-06-09  |  20KB  |  662 lines

  1. // this file is the JavaScript backing for the UI wrangling which happens in
  2. // browser.xul. It also initializes the Greasemonkey singleton which contains
  3. // all the main injection logic, though that should probably be a proper XPCOM
  4. // service and wouldn't need to be initialized in that case.
  5.  
  6. var GM_BrowserUI = new Object();
  7.  
  8. /**
  9.  * nsISupports.QueryInterface
  10.  */
  11. GM_BrowserUI.QueryInterface = function(aIID) {
  12.   if (!aIID.equals(Components.interfaces.nsISupports) &&
  13.       !aIID.equals(Components.interfaces.gmIBrowserWindow) &&
  14.       !aIID.equals(Components.interfaces.nsISupportsWeakReference) &&
  15.       !aIID.equals(Components.interfaces.nsIWebProgressListener))
  16.     throw Components.results.NS_ERROR_NO_INTERFACE;
  17.  
  18.   return this;
  19. };
  20.  
  21.  
  22. /**
  23.  * Called when this file is parsed, by the last line. Set up initial objects,
  24.  * do version checking, and set up listeners for browser xul load and location
  25.  * changes.
  26.  */
  27. GM_BrowserUI.init = function() {
  28.   this.menuCommanders = [];
  29.   this.currentMenuCommander = null;
  30.  
  31.   GM_listen(window, "load", GM_hitch(this, "chromeLoad"));
  32.   GM_listen(window, "unload", GM_hitch(this, "chromeUnload"));
  33. };
  34.  
  35. /**
  36.  * The browser XUL has loaded. Find the elements we need and set up our
  37.  * listeners and wrapper objects.
  38.  */
  39. GM_BrowserUI.chromeLoad = function(e) {
  40.   // get all required DOM elements
  41.   this.tabBrowser = document.getElementById("content");
  42.   this.appContent = document.getElementById("appcontent");
  43.   this.contextMenu = document.getElementById("contentAreaContextMenu");
  44.   this.statusImage = document.getElementById("gm-status-image");
  45.   this.statusLabel = document.getElementById("gm-status-label");
  46.   this.statusPopup = document.getElementById("gm-status-popup");
  47.   this.statusEnabledItem = document.getElementById("gm-status-enabled-item");
  48.   this.generalMenuEnabledItem = document.getElementById("gm-general-menu-enabled-item");
  49.   this.toolsMenu = document.getElementById("menu_ToolsPopup");
  50.   this.bundle = document.getElementById("gm-browser-bundle");
  51.  
  52.   // seamonkey compat
  53.   if (!this.toolsMenu) {
  54.     this.toolsMenu = document.getElementById("taskPopup");
  55.   }
  56.  
  57.   // songbird compat
  58.   if (!this.appContent && this.tabBrowser) {
  59.     this.appContent = this.tabBrowser.parentNode;
  60.   }
  61.  
  62.   // update visual status when enabled state changes
  63.   this.enabledWatcher = GM_hitch(this, "refreshStatus");
  64.   GM_prefRoot.watch("enabled", this.enabledWatcher);
  65.  
  66.   // hook various events
  67.   GM_listen(this.appContent, "DOMContentLoaded", GM_hitch(this, "contentLoad"));
  68.   GM_listen(this.contextMenu, "popupshowing", GM_hitch(this, "contextMenuShowing"));
  69.   GM_listen(this.toolsMenu, "popupshowing", GM_hitch(this, "toolsMenuShowing"));
  70.  
  71.   // listen for clicks on the install bar
  72.   Components.classes["@mozilla.org/observer-service;1"]
  73.             .getService(Components.interfaces.nsIObserverService)
  74.             .addObserver(this, "install-userscript", true);
  75.  
  76.   // we use this to determine if we are the active window sometimes
  77.   this.winWat = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  78.                           .getService(Components.interfaces.nsIWindowWatcher);
  79.  
  80.   // this gives us onLocationChange
  81.   this.tabBrowser.addProgressListener(this,
  82.     Components.interfaces.nsIWebProgress.NOTIFY_LOCATION);
  83.  
  84.   // update enabled icon
  85.   this.refreshStatus();
  86.  
  87.   // register for notifications from greasemonkey-service about ui type things
  88.   this.gmSvc = Components.classes["@greasemonkey.mozdev.org/greasemonkey-service;1"]
  89.                          .getService(Components.interfaces.gmIGreasemonkeyService);
  90.  
  91.   this.gmSvc.registerBrowser(this);
  92. };
  93.  
  94. /**
  95.  * gmIBrowserWindow.registerMenuCommand
  96.  */
  97. GM_BrowserUI.registerMenuCommand = function(menuCommand) {
  98.   if (this.isMyWindow(menuCommand.window)) {
  99.     var commander = this.getCommander(menuCommand.window);
  100.  
  101.     commander.registerMenuCommand(menuCommand.name,
  102.                                   menuCommand.doCommand,
  103.                                   menuCommand.accelKey,
  104.                                   menuCommand.accelModifiers,
  105.                                   menuCommand.accessKey);
  106.   }
  107. };
  108.  
  109. /**
  110.  * gmIBrowserWindow.openInTab
  111.  */
  112. GM_BrowserUI.openInTab = function(domWindow, url) {
  113.   if (this.isMyWindow(domWindow)) {
  114.     this.tabBrowser.addTab(url);
  115.   }
  116. };
  117.  
  118. /**
  119.  * Gets called when a DOMContentLoaded event occurs somewhere in the browser.
  120.  * If that document is in in the top-level window of the focused tab, find
  121.  * it's menu items and activate them.
  122.  */
  123. GM_BrowserUI.contentLoad = function(e) {
  124.   var safeWin;
  125.   var unsafeWin;
  126.   var href;
  127.   var commander;
  128.  
  129.   if (!GM_getEnabled()) {
  130.     return;
  131.   }
  132.  
  133.   safeWin = e.target.defaultView;
  134.   unsafeWin = safeWin.wrappedJSObject;
  135.   href = safeWin.location.href;
  136.  
  137.   if (GM_isGreasemonkeyable(href)) {
  138.     commander = this.getCommander(unsafeWin);
  139.  
  140.     // if this content load is in the focused tab, attach the menuCommaander
  141.     if (unsafeWin == this.tabBrowser.selectedBrowser.contentWindow) {
  142.       this.currentMenuCommander = commander;
  143.       this.currentMenuCommander.attach();
  144.     }
  145.  
  146.     this.gmSvc.domContentLoaded({ wrappedJSObject: unsafeWin }, window);
  147.  
  148.     GM_listen(unsafeWin, "pagehide", GM_hitch(this, "contentUnload"));
  149.   }
  150.  
  151.   // Show the greasemonkey install banner if we are navigating to a .user.js
  152.   // file in a top-level tab.
  153.   if (href.match(/\.user\.js$/) && safeWin == safeWin.top) {
  154.     var browser = this.tabBrowser.getBrowserForDocument(safeWin.document);
  155.     this.showInstallBanner(browser);
  156.   }
  157. };
  158.  
  159.  
  160. /**
  161.  * Shows the install banner across the top of the tab that is displayed when
  162.  * a user selects "show script source" in the install dialog.
  163.  */
  164. GM_BrowserUI.showInstallBanner = function(browser) {
  165.   var greeting = this.bundle.getString("greeting.msg");
  166.  
  167.   if (this.tabBrowser.showMessage) {
  168.     // Firefox 1.5 and lower
  169.     this.tabBrowser.showMessage(
  170.       browser,
  171.       "chrome://greasemonkey/content/icon_small.png",
  172.       greeting,
  173.       this.bundle.getString("greeting.btn"),
  174.       null /* default doc shell */,
  175.       "install-userscript",
  176.       null /* no popuup */,
  177.       "top",
  178.       true /* show close button */,
  179.       this.bundle.getString("greeting.btnAccess") /* access key */);
  180.   } else {
  181.     // Firefox 2.0+
  182.     var notificationBox = this.tabBrowser.getNotificationBox(browser);
  183.  
  184.     // Remove existing notifications. Notifications get removed
  185.     // automatically onclick and on page navigation, but we need to remove
  186.     // them ourselves in the case of reload, or they stack up.
  187.     for (var i = 0, child; child = notificationBox.childNodes[i]; i++) {
  188.       if (child.getAttribute("value") == "install-userscript") {
  189.         notificationBox.removeNotification(child);
  190.       }
  191.     }
  192.  
  193.     var notification = notificationBox.appendNotification(
  194.       greeting,
  195.       "install-userscript",
  196.       "chrome://greasemonkey/content/icon_small.png",
  197.       notificationBox.PRIORITY_WARNING_MEDIUM,
  198.       [{
  199.         label: this.bundle.getString("greeting.btn"),
  200.         accessKey: this.bundle.getString("greeting.btnAccess"),
  201.         popup: null,
  202.         callback: GM_hitch(this, "installCurrentScript")
  203.       }]
  204.     );
  205.   }
  206. };
  207.  
  208. /**
  209.  * Called from greasemonkey service when we should load a user script.
  210.  */
  211. GM_BrowserUI.startInstallScript = function(uri, timer) {
  212.   if (!timer) {
  213.     // docs for nsicontentpolicy say we're not supposed to block, so short
  214.     // timer.
  215.     window.setTimeout(
  216.       function() { GM_BrowserUI.startInstallScript(uri, true) }, 0);
  217.  
  218.     return;
  219.   }
  220.  
  221.   this.scriptDownloader_ = new ScriptDownloader(window, uri, this.bundle);
  222.   this.scriptDownloader_.startInstall();
  223. };
  224.  
  225.  
  226. /**
  227.  * Open the tab to show the contents of a script and display the banner to let
  228.  * the user install it.
  229.  */
  230. GM_BrowserUI.showScriptView = function(scriptDownloader) {
  231.   this.scriptDownloader_ = scriptDownloader;
  232.  
  233.   var tab = this.tabBrowser.addTab(scriptDownloader.script.previewURL);
  234.   var browser = this.tabBrowser.getBrowserForTab(tab);
  235.  
  236.   this.tabBrowser.selectedTab = tab;
  237. };
  238.  
  239. /**
  240.  * Implements nsIObserve.observe. Right now we're only observing our own
  241.  * install-userscript, which happens when the install bar is clicked.
  242.  */
  243. GM_BrowserUI.observe = function(subject, topic, data) {
  244.   if (topic == "install-userscript") {
  245.     if (window == this.winWat.activeWindow) {
  246.       this.installCurrentScript();
  247.     }
  248.   } else {
  249.     throw new Error("Unexpected topic received: {" + topic + "}");
  250.   }
  251. };
  252.  
  253. /**
  254.  * Handles the install button getting clicked.
  255.  */
  256. GM_BrowserUI.installCurrentScript = function() {
  257.   this.scriptDownloader_.installScript();
  258. };
  259.  
  260. GM_BrowserUI.installScript = function(script){
  261.   GM_getConfig().install(script);
  262.   this.showHorrayMessage(script.name);
  263. };
  264.  
  265. /**
  266.  * The browser's location has changed. Usually, we don't care. But in the case
  267.  * of tab switching we need to change the list of commands displayed in the
  268.  * User Script Commands submenu.
  269.  */
  270. GM_BrowserUI.onLocationChange = function(a,b,c) {
  271.   if (this.currentMenuCommander != null) {
  272.     this.currentMenuCommander.detach();
  273.     this.currentMenuCommander = null;
  274.   }
  275.  
  276.   var menuCommander = this.getCommander(this.tabBrowser.selectedBrowser.
  277.                                         contentWindow);
  278.  
  279.   if (menuCommander) {
  280.     this.currentMenuCommander = menuCommander;
  281.     this.currentMenuCommander.attach();
  282.   }
  283. };
  284.  
  285. /**
  286.  * A content document has unloaded. We need to remove it's menuCommander to
  287.  * avoid leaking it's memory.
  288.  */
  289. GM_BrowserUI.contentUnload = function(e) {
  290.   if (e.persisted) {
  291.     return;
  292.   }
  293.  
  294.   var unsafeWin = e.target.defaultView;
  295.  
  296.   // remove the commander for this document
  297.   var commander = null;
  298.  
  299.   // looping over commanders rather than using getCommander because we need
  300.   // the index into commanders.splice.
  301.   for (var i = 0; item = this.menuCommanders[i]; i++) {
  302.     if (item.win == unsafeWin) {
  303.  
  304.       if (item.commander == this.currentMenuCommander) {
  305.         this.currentMenuCommander.detach();
  306.         this.currentMenuCommander = null;
  307.       }
  308.  
  309.       this.menuCommanders.splice(i, 1);
  310.  
  311.       break;
  312.     }
  313.   }
  314. };
  315.  
  316. /**
  317.  * The browser XUL has unloaded. We need to let go of the pref watcher so
  318.  * that a non-existant window is not informed when greasemonkey enabled state
  319.  * changes. And we need to let go of the progress listener so that we don't
  320.  * leak it's memory.
  321.  */
  322. GM_BrowserUI.chromeUnload = function() {
  323.   GM_prefRoot.unwatch("enabled", this.enabledWatcher);
  324.   this.tabBrowser.removeProgressListener(this);
  325.   this.gmSvc.unregisterBrowser(this);
  326.   delete this.menuCommanders;
  327. };
  328.  
  329. /**
  330.  * Called when the content area context menu is showing. We figure out whether
  331.  * to show our context items.
  332.  */
  333. GM_BrowserUI.contextMenuShowing = function() {
  334.   var contextItem = ge("view-userscript");
  335.   var contextSep = ge("install-userscript-sep");
  336.  
  337.   var culprit = document.popupNode;
  338.  
  339.   while (culprit && culprit.tagName && culprit.tagName.toLowerCase() != "a") {
  340.      culprit = culprit.parentNode;
  341.   }
  342.  
  343.   contextItem.hidden =
  344.     contextSep.hidden =
  345.     !this.getUserScriptLinkUnderPointer();
  346. };
  347.  
  348.  
  349. GM_BrowserUI.getUserScriptLinkUnderPointer = function() {
  350.   var culprit = document.popupNode;
  351.  
  352.   while (culprit && culprit.tagName && culprit.tagName.toLowerCase() != "a") {
  353.      culprit = culprit.parentNode;
  354.   }
  355.  
  356.   if (!culprit || !culprit.href ||
  357.       !culprit.href.match(/\.user\.js(\?|$)/i)) {
  358.     return null;
  359.   }
  360.  
  361.   var ioSvc = Components.classes["@mozilla.org/network/io-service;1"]
  362.                         .getService(Components.interfaces.nsIIOService);
  363.   var uri = ioSvc.newURI(culprit.href, null, null);
  364.  
  365.   return uri;
  366. };
  367.  
  368. GM_BrowserUI.toolsMenuShowing = function() {
  369.   var installItem = ge("userscript-tools-install");
  370.   var hidden = true;
  371.  
  372.   if (window._content && window._content.location &&
  373.       window.content.location.href.match(/\.user\.js(\?|$)/i)) {
  374.     hidden = false;
  375.   }
  376.  
  377.   // Better to use hidden than collapsed because collapsed still allows you to
  378.   // select the item using keyboard navigation, but hidden doesn't.
  379.   installItem.setAttribute("hidden", hidden.toString());
  380. };
  381.  
  382.  
  383. /**
  384.  * Helper method which gets the menuCommander corresponding to a given
  385.  * document
  386.  */
  387. GM_BrowserUI.getCommander = function(unsafeWin) {
  388.   for (var i = 0; i < this.menuCommanders.length; i++) {
  389.     if (this.menuCommanders[i].win == unsafeWin) {
  390.       return this.menuCommanders[i].commander;
  391.     }
  392.   }
  393.  
  394.   // no commander found. create one and add it.
  395.   var commander = new GM_MenuCommander(document);
  396.   this.menuCommanders.push({win:unsafeWin, commander:commander});
  397.  
  398.   return commander;
  399. };
  400.  
  401. /**
  402.  * Helper to determine if a given dom window is in this tabbrowser
  403.  */
  404. GM_BrowserUI.isMyWindow = function(domWindow) {
  405.   var tabbrowser = getBrowser();
  406.   var browser;
  407.  
  408.   for (var i = 0; browser = tabbrowser.browsers[i]; i++) {
  409.     if (browser.contentWindow == domWindow) {
  410.       return true;
  411.     }
  412.   }
  413.  
  414.   return false;
  415. };
  416.  
  417. function GM_showGeneralPopup(aEvent) {
  418.   // set the enabled/disabled state
  419.   GM_BrowserUI.generalMenuEnabledItem.setAttribute("checked", GM_getEnabled());
  420. }
  421.  
  422. function GM_showPopup(aEvent) {
  423.   function urlsOfAllFrames(contentWindow) {
  424.     function collect(contentWindow) {
  425.       urls = urls.concat(urlsOfAllFrames(contentWindow));
  426.     }
  427.     var urls = [contentWindow.location.href];
  428.     Array.prototype.slice.call(contentWindow.frames).forEach(collect);
  429.     return urls;
  430.   }
  431.  
  432.   function uniq(a) {
  433.     var seen = {}, list = [], item;
  434.     for (var i = 0; i < a.length; i++) {
  435.       item = a[i];
  436.       if (!seen.hasOwnProperty(item))
  437.         seen[item] = list.push(item);
  438.     }
  439.     return list;
  440.   }
  441.  
  442.   function scriptsMatching(urls) {
  443.  
  444.     function testMatchURLs(script) {
  445.  
  446.       function testMatchURL(url) {
  447.         return script.matchesURL(url);
  448.       }
  449.  
  450.       return urls.some(testMatchURL);
  451.     }
  452.  
  453.     return GM_getConfig().getMatchingScripts(testMatchURLs);
  454.   }
  455.  
  456.   function appendScriptToPopup(script) {
  457.     var mi = document.createElement("menuitem");
  458.     mi.setAttribute("label", script.name);
  459.     mi.script = script;
  460.     mi.setAttribute("type", "checkbox");
  461.     mi.setAttribute("checked", script.enabled.toString());
  462.     popup.insertBefore(mi, tail);
  463.   }
  464.  
  465.   var popup = aEvent.target;
  466.   var tail = document.getElementById("gm-status-no-scripts-sep");
  467.  
  468.   // set the enabled/disabled state
  469.   GM_BrowserUI.statusEnabledItem.setAttribute("checked", GM_getEnabled());
  470.  
  471.   // remove all the scripts from the list
  472.   for (var i = popup.childNodes.length - 1; i >= 0; i--) {
  473.     if (popup.childNodes[i].script) {
  474.       popup.removeChild(popup.childNodes[i]);
  475.     }
  476.   }
  477.  
  478.   var urls = uniq( urlsOfAllFrames( getBrowser().contentWindow ));
  479.   var runsOnTop = scriptsMatching( [urls.shift()] ); // first url = top window
  480.   var runsFramed = scriptsMatching( urls ); // remainder are all its subframes
  481.  
  482.   // drop all runsFramed scripts already present in runsOnTop
  483.   for (var i = 0; i < runsOnTop.length; i++) {
  484.     var j = 0, item = runsOnTop[i];
  485.     while (j < runsFramed.length) {
  486.       if (item === runsFramed[j]) {
  487.         runsFramed.splice(j, 1);
  488.       } else {
  489.         j++;
  490.       }
  491.     }
  492.   }
  493.  
  494.   // build the new list of scripts
  495.   if (runsFramed.length) {
  496.     runsFramed.forEach(appendScriptToPopup);
  497.     var separator = document.createElement("menuseparator");
  498.     separator.setAttribute("value", "hack"); // to get removed in the loop above
  499.     popup.insertBefore(separator, tail);
  500.   }
  501.   runsOnTop.forEach(appendScriptToPopup);
  502.  
  503.   var foundInjectedScript = !!(runsFramed.length + runsOnTop.length);
  504.   document.getElementById("gm-status-no-scripts").collapsed = foundInjectedScript;
  505. }
  506.  
  507. /**
  508.  * Handle clicking one of the items in the popup. Left-click toggles the enabled
  509.  * state, rihgt-click opens in an editor.
  510.  */
  511. function GM_popupClicked(aEvent) {
  512.   if (aEvent.button == 0 || aEvent.button == 2) {
  513.     var script = aEvent.target.script;
  514.     if (!script) return;
  515.  
  516.     if (aEvent.button == 0) // left-click: toggle enabled state
  517.       script.enabled =! script.enabled;
  518.     else // right-click: open in editor
  519.       openInEditor(script);
  520.  
  521.     closeMenus(aEvent.target);
  522.   }
  523. }
  524.  
  525. /**
  526.  * Greasemonkey's enabled state has changed, either as a result of clicking
  527.  * the icon in this window, clicking it in another window, or even changing
  528.  * the mozilla preference that backs it directly.
  529.  */
  530. GM_BrowserUI.refreshStatus = function() {
  531.   if (GM_getEnabled()) {
  532.     this.statusImage.src = "chrome://greasemonkey/content/icon_small.png";
  533.     this.statusImage.tooltipText = this.bundle.getString("tooltip.enabled");
  534.   } else {
  535.     this.statusImage.src = "chrome://greasemonkey/content/icon_small_disabled.png";
  536.     this.statusImage.tooltipText = this.bundle.getString("tooltip.disabled");
  537.   }
  538.  
  539.   this.statusImage.style.opacity = "1.0";
  540. };
  541.  
  542. GM_BrowserUI.newUserScript = function() {
  543.   var windowWatcher = Components
  544.     .classes["@mozilla.org/embedcomp/window-watcher;1"]
  545.     .getService(Components.interfaces.nsIWindowWatcher);
  546.   windowWatcher.openWindow(
  547.     window, "chrome://greasemonkey/content/newscript.xul", null,
  548.     "chrome,dependent,centerscreen,resizable,dialog", null
  549.   );
  550. };
  551.  
  552. GM_BrowserUI.showStatus = function(message, autoHide) {
  553.   if (this.statusLabel.collapsed) {
  554.     this.statusLabel.collapsed = false;
  555.   }
  556.  
  557.   message += " ";
  558.  
  559.   var box = document.createElement("vbox");
  560.   var label = document.createElement("label");
  561.   box.style.position = "fixed";
  562.   box.style.left = "-10000px";
  563.   box.style.top = "-10000px";
  564.   box.style.border = "5px solid red";
  565.   box.appendChild(label);
  566.   document.documentElement.appendChild(box);
  567.   label.setAttribute("value", message);
  568.  
  569.   var current = parseInt(this.statusLabel.style.width);
  570.   this.statusLabel.value = message;
  571.   var max = label.boxObject.width;
  572.  
  573.   this.showAnimation = new Accelimation(this.statusLabel.style,
  574.                                           "width", max, 300, 2, "px");
  575.   this.showAnimation.onend = GM_hitch(this, "showStatusAnimationEnd", autoHide);
  576.   this.showAnimation.start();
  577. };
  578.  
  579. GM_BrowserUI.showStatusAnimationEnd = function(autoHide) {
  580.   this.showAnimation = null;
  581.  
  582.   if (autoHide) {
  583.     this.setAutoHideTimer();
  584.   }
  585. };
  586.  
  587. GM_BrowserUI.setAutoHideTimer = function() {
  588.   if (this.autoHideTimer) {
  589.     window.clearTimeout(this.autoHideTimer);
  590.   }
  591.  
  592.   this.autoHideTimer = window.setTimeout(GM_hitch(this, "hideStatus"), 3000);
  593. };
  594.  
  595. GM_BrowserUI.hideStatusImmediately = function() {
  596.   if (this.showAnimation) {
  597.     this.showAnimation.stop();
  598.     this.showAnimation = null;
  599.   }
  600.  
  601.   if (this.hideAnimation) {
  602.     this.hideAnimation.stop();
  603.     this.hideAnimation = null;
  604.   }
  605.  
  606.   if (this.autoHideTimer) {
  607.     window.clearTimeout(this.autoHideTimer);
  608.     this.autoHideTimer = null;
  609.   }
  610.  
  611.   this.statusLabel.style.width = "0";
  612.   this.statusLabel.collapsed = true;
  613. };
  614.  
  615. GM_BrowserUI.hideStatus = function() {
  616.   if (!this.hideAnimation) {
  617.     this.autoHideTimer = null;
  618.     this.hideAnimation = new Accelimation(this.statusLabel.style,
  619.                                             "width", 0, 300, 2, "px");
  620.     this.hideAnimation.onend = GM_hitch(this, "hideStatusAnimationEnd");
  621.     this.hideAnimation.start();
  622.   }
  623. };
  624.  
  625. GM_BrowserUI.hideStatusAnimationEnd = function() {
  626.   this.hideAnimation = null;
  627.   this.statusLabel.collapsed = true;
  628. };
  629.  
  630. // necessary for webProgressListener implementation
  631. GM_BrowserUI.onProgressChange = function(webProgress,b,c,d,e,f){};
  632. GM_BrowserUI.onStateChange = function(a,b,c,d){};
  633. GM_BrowserUI.onStatusChange = function(a,b,c,d){};
  634. GM_BrowserUI.onSecurityChange = function(a,b,c){};
  635. GM_BrowserUI.onLinkIconAvailable = function(a){};
  636.  
  637. GM_BrowserUI.showHorrayMessage = function(scriptName) {
  638.   this.showStatus("'" + scriptName + "' " + this.bundle.getString("statusbar.installed"), true);
  639. };
  640.  
  641. GM_BrowserUI.installMenuItemClicked = function() {
  642.   GM_BrowserUI.startInstallScript(
  643.     gBrowser.currentURI
  644.   );
  645. };
  646.  
  647. GM_BrowserUI.viewContextItemClicked = function() {
  648.   var uri = GM_BrowserUI.getUserScriptLinkUnderPointer();
  649.  
  650.   this.scriptDownloader_ = new ScriptDownloader(window, uri, this.bundle);
  651.   this.scriptDownloader_.startViewScript();
  652. };
  653.  
  654. GM_BrowserUI.manageMenuItemClicked = function() {
  655.    GM_openUserScriptManager();
  656. };
  657.  
  658. //loggify(GM_BrowserUI, "GM_BrowserUI");
  659.  
  660. log("calling init...");
  661. GM_BrowserUI.init();
  662.